package com.wframe.project.jnd.wx.wxImpl;


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import com.frame.common.Xml;
import com.frame.util.DataConvert;

public class WeixInterfaceImpl {
	
	private String randomstr="abcdefghijklmnopqrstuvwxyz0123456789";

    public String getAccessToken() throws Exception{
        HttpClient httpclient=new DefaultHttpClient();
        HttpGet get=new HttpGet(WeixAccountConfig.getConfig().getApiUrl()+"/token?grant_type=client_credential&appid="+WeixAccountConfig.getConfig().getAppId()+"&secret="+WeixAccountConfig.getConfig().getSecret());
        HttpResponse response = httpclient.execute(get); 
        HttpEntity entitys = response.getEntity(); 
        String token="";
        if (entitys != null) {  
            String remes=EntityUtils.toString(entitys);  
            JSONObject json=new JSONObject(remes);
            token=json.getString("access_token");
        } 
        return token;
    }
    public void createMenu(String json) throws Exception{
        HttpClient httpclient=new DefaultHttpClient();
        String t=AccessTokenSession.getAccessToken();
        HttpPost post=new HttpPost(WeixAccountConfig.getConfig().getApiUrl()+"/menu/create?access_token="+t);
        post.setEntity(new StringEntity(json, "UTF-8"));
        HttpResponse response = httpclient.execute(post); 
        HttpEntity entitys = response.getEntity();
        if (entitys != null) {  
            String remes=EntityUtils.toString(entitys);  
            System.out.println(remes);
        }
    }
    public void delMenu() throws Exception{
        HttpClient httpclient=new DefaultHttpClient();
        String t=AccessTokenSession.getAccessToken();
        HttpPost post=new HttpPost(WeixAccountConfig.getConfig().getApiUrl()+"/menu/delete?access_token="+t);
        
        HttpResponse response = httpclient.execute(post); 
        HttpEntity entitys = response.getEntity(); 
    }
    public String getOpenId(String code) throws Exception
    {
        String url = WeixAccountConfig.getConfig().getOauthUrl()+"?appid="+WeixAccountConfig.getConfig().getAppId()+"&secret=" + WeixAccountConfig.getConfig().getSecret() + "&code=" + code + "&grant_type=authorization_code";
        HttpClient httpclient=new DefaultHttpClient();
        HttpGet get=new HttpGet(url);
        HttpResponse response = httpclient.execute(get); 
        HttpEntity entitys = response.getEntity(); 
        String openid="";
        try{
            if (entitys != null) {  
                String remes=EntityUtils.toString(entitys);
                JSONObject json=new JSONObject(remes);
                openid=json.getString("openid");
            }
        }catch(Exception e){e.printStackTrace();}
        return openid;
    }
    
    public String getJsTicket() throws Exception{
    	String t=AccessTokenSession.getAccessToken();
    	String url = WeixAccountConfig.getConfig().getApiUrl()+"/ticket/getticket?access_token="+t+"&type=jsapi";
        HttpClient httpclient=new DefaultHttpClient();
        HttpGet get=new HttpGet(url);
        HttpResponse response = httpclient.execute(get); 
        HttpEntity entitys = response.getEntity(); 
        String ticket="";
        try{
	        if (entitys != null) {  
	            String remes=EntityUtils.toString(entitys);
	            JSONObject json=new JSONObject(remes);
	            ticket=json.getString("ticket");
	        }
        }catch(Exception e){e.printStackTrace();}
        return ticket;
    }
    
    public void sendText(String openid,String data) throws Exception{
        HttpClient httpclient=new DefaultHttpClient();
        String t=AccessTokenSession.getAccessToken();
        HttpPost post=new HttpPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+t);
        StringBuffer sb = new StringBuffer();
        sb.append("{");
        sb.append("\"touser\":\""+openid+"\",");
        sb.append("\"template_id\":\""+WeixAccountConfig.getConfig().getTemplateid()+"\",");
        sb.append("\"data\":"+data);
        sb.append("}");
        post.setEntity(new StringEntity(sb.toString(), "UTF-8"));
        HttpResponse response = httpclient.execute(post); 
        HttpEntity entitys = response.getEntity();
    }
    
    public String getPrepay_id(String title,String orderId,double paymoney,String ip,String notifyurl,String openid) throws Exception{
    	int money=new Double(DataConvert.doubleMul(paymoney,100)).intValue();//元转分
    	Map<String, String> parms=new HashMap<String, String>();
    	parms.put("appid", WeixAccountConfig.getConfig().getAppId());
    	parms.put("mch_id", WeixAccountConfig.getConfig().getMch_id());
    	parms.put("device_info", "WEB");
    	parms.put("nonce_str",paynonce_str(16));
    	parms.put("body", title);
    	parms.put("out_trade_no",orderId); 
    	parms.put("total_fee",String.valueOf(money));
    	parms.put("spbill_create_ip",ip);
    	parms.put("notify_url",notifyurl);
    	parms.put("trade_type","JSAPI");
    	parms.put("openid",openid);
    	String sign=WeixSign.paysign(parms);
    	parms.put("sign", sign);
    	
    	StringBuffer xmlstr=new StringBuffer("<xml>");
    	Iterator it=parms.entrySet().iterator();
	 	while(it.hasNext()){
	 		Map.Entry ent=(Map.Entry)it.next();
	 		Object v=ent.getValue();
	 		String k = (String)ent.getKey();
	 		if(v!=null && !"".equals(v.toString())){
	 			xmlstr.append("<"+k+">"+"<![CDATA["+v.toString()+"]]></"+k+">");
	 		}	
	 	}
	 	xmlstr.append("</xml>");
	 	Logger.getLogger(WeixSign.class).info(xmlstr.toString());
	 	
        String rexml=postRequest(xmlstr.toString());
        String pay_id="";
        Logger.getLogger(WeixSign.class).info("下单回执："+rexml);
        if(rexml.length()>0){
        	SortedMap<String, String> redata=parseXml(rexml);
        	String return_code=redata.get("return_code");
        	if(!"SUCCESS".equalsIgnoreCase(return_code)){
        		Logger.getLogger(this.getClass()).error("微信支付下单错误:"+redata.get("return_msg"));
        		throw new Exception(redata.get("return_msg")+"，无法发起微信支付");
        	}
        	String result_code=redata.get("result_code");
        	if(!"SUCCESS".equalsIgnoreCase(result_code)){
        		Logger.getLogger(this.getClass()).error("微信支付下单错误:"+redata.get("err_code_des"));
        		throw new Exception(redata.get("err_code_des")+"，无法发起微信支付");
        	}
        	redata.remove("return_code");
        	redata.remove("return_msg");
        	String v=redata.get("prepay_id");
        	if(StringUtils.isNotBlank(v))pay_id=v;
        }
        return pay_id;
    }
    
    public String paynonce_str(int length){
    	Random random = new Random();     
        StringBuffer sb = new StringBuffer();     
        for (int i = 0; i < length; i++) {     
            int number = random.nextInt(randomstr.length());     
            sb.append(randomstr.charAt(number));     
        }     
        return sb.toString(); 
    }
    
    private String postRequest(String parms) throws Exception{
    	// 创建SSLContext对象，并使用我们指定的信任管理器初始化
		X509TrustManager tm = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }
            @Override
            public void checkServerTrusted(X509Certificate[] chain,
                                           String authType) throws CertificateException {
            }
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        TrustManager[] tms={tm};
        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
        sslContext.init(null, tms, new java.security.SecureRandom());
        // 从上述SSLContext对象中得到SSLSocketFactory对象
        SSLSocketFactory ssf = sslContext.getSocketFactory();
        URL url = new URL(WeixAccountConfig.getConfig().getPayApiUrl());
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setSSLSocketFactory(ssf);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        // 设置请求方式（GET/POST）
        conn.setRequestMethod("POST");
        conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
        OutputStream outputStream = conn.getOutputStream();
        // 注意编码格式
        outputStream.write(parms.getBytes("UTF-8"));
        outputStream.close();
        // 从输入流读取返回内容
        InputStream inputStream = conn.getInputStream();
        InputStreamReader inputStreamReader=null;
        BufferedReader bufferedReader=null;
        StringBuffer buffer = new StringBuffer();
        try{
	        inputStreamReader = new InputStreamReader(inputStream, "utf-8");
	        bufferedReader = new BufferedReader(inputStreamReader);
	        String str = null;
	        while ((str = bufferedReader.readLine()) != null) {
	            buffer.append(str);
	        }
        }finally{
        	 // 释放资源
            try{if(bufferedReader!=null)bufferedReader.close();}catch(Exception e){}
            try{if(inputStreamReader!=null)inputStreamReader.close();}catch(Exception e){}
            try{if(inputStream!=null)inputStream.close();}catch(Exception e){}
            inputStream = null;
            try{if(conn!=null)conn.disconnect();}catch(Exception e){}
        }
        return buffer.toString();
    }
    
    public SortedMap parseXml(String xml) throws Exception{
    	SortedMap<String, String> redata=new TreeMap<String, String>();
    	Document doc= Xml.createDocument(xml.getBytes("UTF-8"));
		Element root = doc.getDocumentElement();
		NodeList nlist=root.getChildNodes();
		for(int i=0;i<nlist.getLength();i++){
			if(nlist.item(i) instanceof Element){
				Element el=(Element)nlist.item(i);
				redata.put(el.getNodeName(), Xml.getElementValue(el));
			}
		}
		return redata;
    }
}
